<?php
require_once('IView.php');
require_once('./helpers/Storage.Helper.php');

class TimeLine implements IView
{
	private $cellWidth = 24;
	private $cellHeight = 24;
	private $days = 30;

	public function GetContents($account)
	{
	    return '<div class="message">loading timeline...</div>';
	}


	public function GetTimeLine(&$lists, $date, $time, $dayOffset, $screenWidth, $screenHeight)
	{
	    $this->days = max(intval($screenWidth / $this->cellWidth), 30);
		$sortedTasks = $this->getSortedTasks($lists, $time, $dayOffset);

  		$rows = '';
		foreach ($sortedTasks as $tasks)
		    foreach ($tasks as $task)
	    		$rows .= $this->getRow($task, $date, $time);

		if (!$rows)
			$rows = '<tr><td class="message" colspan="'.$this->days.'">No tasks to display.</td></tr>';

		$html  = '<div id="timeline" onmousedown="timeline.MoveTimeline(event); return false"><table>';
		$html .= '<thead>'.$this->getHeadings($date, $dayOffset).'</thead>';
		$html .= '<tbody>'.$rows.'</tbody>';
		$html .= '</table></div>';
		return $html;
	}
	
	
	private function getSortedTasks(&$lists, $time, $dayOffset)
	{
		$sorted = array();
		$endtime = $time + $this->days * 86400;

		foreach ($lists as $list)
		{
		    if ($list['Minimized'])
		        continue;
		        
			foreach ($list['Tasks'] as $task)
			{
			    // correction of unassigned deadline
			    if (empty($task['Deadline']))
			        continue;

				// correction of deadline of tasks which already ended
				if ($task['State'] > 1 && !empty($task['End']))
                   	$task['Deadline'] = $task['End'];

				// overdated tasks
				if ($task['State'] < 2 && $dayOffset <= 0 && $task['Deadline'] < $time)
					$task['Deadline'] = $time;

				// validation of time frame
				if ($task['Start'] > $endtime || $task['Deadline'] < $time)
				    continue;

		    	$task['ListId'] = $list['Id'];
		        $task['ListCategory'] = $list['Category'];

		        $key = date('Ymd', $task['Start']).date('Ymd', $task['Deadline']).$list['Category'].(3 - $task['State']).$task['Id'];
		        
		    	if (isset($sorted[$key]))
					array_push($sorted[$key], $task);
				else
					$sorted[$key] = array($task);
			}
		}

		ksort($sorted);
		return $sorted;
	}
	
	
	private function getHeadings($date, $dayOffset)
	{
		$html = '<tr class="weekHeadings">';
		$wday = (6 + $date['wday']) % 7;
		$dst = 6 - $wday;
  		$time = $date[0];

		for ($i = 0; $i < $this->days; $i++)
		{
			$span = (($i - $dst) % 7) == 1 ? ($this->days - $i > 6 ? 7 : ($this->days - $i)) : ($i ? 0 : 7 - $wday);
		    if ($span)
		    {
		    	$i += $span - 1;
				$html .= '<th colspan="'.$span.'">'.($span > 3 ? date('j M', $time + 86400 * ($i - $span + 1)) : '').'</th>';
			}
		}
		
		$html .= '</tr><tr class="dayHeadings">';
		for ($i = 0; $i < $this->days; $i++)
	    {
	        $class  = $i == -$dayOffset ? 'today' : '';
			$class .= !(($i - $dst) % 7) ? ' endofweek' : '';
	        $html .= '<th class="'.$class.'" title="'.date('D M d Y', $time).'"><a href="javascript:tasklists.SetDate(\''.date('Y/m/d', $time).'\')">'.substr(date('D', $time), 0, 2).'</th>';
	        $time += 86400;
	    }
	    
	    $html .= '</tr>';
	    return $html;
	}
	
	
	private function getRow(&$task, $date, $time)
	{
	    $className = '';
		if (!empty($task['Tags']))
			foreach ($task['Tags'] as $tag)
				$className .= ' '.$tag;

		$maxWidth = $this->cellWidth * $this->days;
		$startIdx = intval(($task['Start'] - $time) / 86400);
		$endIdx = intval(($task['Deadline'] - $time) / 86400);

		$on = $task['State'] < 2;
		$dst = 7 - $date['wday'];
		$taskId = $task['Id'];
		
		$html = '<tr id="Line'.$taskId.'">';
	    for ($i = 0; $i < $this->days; $i++)
	    {
	    	$class  = !(($i - $dst) % 7) ? ' endofweek' : '';
	    	$class .= $on ? '' : ' finished';

	        if ($on && $i == $startIdx - 1)
	        	$html .= '<td class="btnStartline'.$class.'" id="SetStart&i='.$taskId.'"><div class="dragger" onmousedown="timeline.SetDateline(event, \''.date('Y/m/d', $task['Start']).'\'); return false"><div class="draggingicon cat'.$task['ListCategory'].'"></div></div></td>';
	        else if ($on && $i == $endIdx + 1)
	        	$html .= '<td class="btnDeadline'.$class.'" id="SetDeadline&i='.$taskId.'"><div class="draggingicon cat'.$task['ListCategory'].'"></div><div class="dragger" onmousedown="timeline.SetDateline(event, \''.date('Y/m/d', $task['Deadline']).'\'); return false"></div></td>';
	        else if ($i >= $startIdx && $i <= $endIdx)
	        {
	            $html .= '<td colspan="'.min($endIdx - $i + 1, $this->days - $i).'" class="filled cat'.$task['ListCategory'].$class.'">';
				$html .= (isset($task['Printed']) ? '' : '<div class="title" style="max-width: '.($maxWidth - $i * $this->cellWidth).'px"><span>'.strip_tags($task['Title']).'</span></div>');
				$html .= $on ? '<div class="dragger" onmousedown="timeline.MoveTimeline(event, \''.$taskId.'\'); return false"></div>' : '';
				$html .= '</td>';
	            $task['Printed'] = true;
	            $i = $endIdx;
	        }
	        else
	        	$html .= '<td class="'.$class.'"></td>';
	        $time += 86400;
	    }
	    
	    $html .= '</tr>';
	    return $html;
	}
}
?>
